package com.luxsoft.siipap.em.replica.validation;

import java.io.IOException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.SqlParameterValue;

import com.luxsoft.siipap.cxc.model.OrigenDeOperacion;
import com.luxsoft.siipap.em.replica.importadores.dbf.DBFReaderTemplate;
import com.luxsoft.siipap.em.replica.importadores.dbf.DBFRowFilter;
import com.luxsoft.siipap.em.replica.importadores.dbf.DBFRowHandler;
import com.luxsoft.siipap.service.ServiceLocator2;
import com.luxsoft.siipap.util.DateUtil;



/**
 * Valida la importacion de ventas
 * 
 * @author Ruben Cancino Ramos
 *
 */
public class ValidadorDeImportacionVentasDBF  {
	
	private DBFReaderTemplate template;
	private Logger logger=Logger.getLogger(getClass());
	
	public ValidadorDeImportacionVentasDBF(){
		template=new DBFReaderTemplate();
	}
	
	public List<SimpleValidator> validar(final Date dia) throws IOException{
		logger.info("Validando fecha:" +DateUtil.convertDateToString(dia));
		FilterHandler filterHandler=new FilterHandler();
		filterHandler.setDia(dia);
		
		//Credito		
		filterHandler.setPrefix("MCR");
		template.setTabla("MOVCRE");
		template.execute(dia,filterHandler,filterHandler, false);
		
		SimpleValidator creVal=new SimpleValidator();
		creVal.setFecha(dia);
		creVal.setEntidad("MOVCRE");
		creVal.setImporteOrigen(filterHandler.getImporte());
		creVal.setImporteOrigenCancelado(filterHandler.getImporteCancelado());
		creVal.setRegistrosOrigen(filterHandler.getRegistros());
		creVal.setRegistrosOrigenCancelados(filterHandler.getRegistrosCancelados());
		
		
		validarTarget(creVal, OrigenDeOperacion.CRE);
		validarTargetCancelados(creVal, OrigenDeOperacion.CRE);
		
		List<SimpleValidator> res=new ArrayList<SimpleValidator>();
		res.add(creVal);
		return res;
		
	}
	
	
	
	private void validarTarget(SimpleValidator validator,OrigenDeOperacion origen){		
		String sql="select count(x.CARGO_ID) as REGISTROS ,sum(x.docto) as MONTO from SX_VENTAS x where x.fecha=? and x.origen=@ORIGEN";
		sql=sql.replaceAll("@ORIGEN", "\'"+origen.name()+"\'");
		Object[] params=new Object[]{new SqlParameterValue(Types.DATE,validator.getFecha())};
		List<Map<String,Number>> res=ServiceLocator2.getJdbcTemplate().queryForList(sql, params);
		if(!res.isEmpty()){
			Map<String,Number> row=res.get(0);
			Number registros=row.get("REGISTROS");
			Number monto=row.get("MONTO");
			validator.setRegistrosDestino(registros!=null?registros.intValue():0);
			validator.setImporteDestino(monto!=null?monto.doubleValue():0);
		}
	}
	
	private void validarTargetCancelados(SimpleValidator validator,OrigenDeOperacion origen){		
		String sql="select count(x.CARGO_ID) as REGISTROS,ifnull(sum(x.DOCUMENTO),0) as MONTO from  sx_cxc_cargos_cancelados x  join SX_VENTAS y on(x.CARGO_ID=y.CARGO_ID)" +
				" where y.fecha=? and y.origen=@ORIGEN";
		sql=sql.replaceAll("@ORIGEN", "\'"+origen.name()+"\'");
		Object[] params=new Object[]{new SqlParameterValue(Types.DATE,validator.getFecha())};
		List<Map<String,Number>> res=ServiceLocator2.getJdbcTemplate().queryForList(sql, params);
		if(!res.isEmpty()){
			Map<String,Number> row=res.get(0);
			Number registros=row.get("REGISTROS");
			Number monto=row.get("MONTO");
			validator.setRegistrosDestinoCancelados(registros!=null?registros.intValue():0);
			validator.setImporteDestinoCancelado(monto!=null?monto.doubleValue():0);
		}
	}
	
	private class FilterHandler implements DBFRowHandler,DBFRowFilter{
		
		private Date dia;
		
		private double importe;
		private double importeCancelado;
		private int registros;
		private int registrosCancelados;
		private String prefix;

		public void setDia(Date dia) {
			this.dia = dia;
			clear();
		}
		
		public void clear(){
			setImporte(0);
			setRegistros(0);
		}

		public void processRow(Map<String, Object> row) throws Exception {
			final long numero=getSafaLong(row, prefix+"NUMDOCT");
			boolean eliminado=(Boolean)row.get("ELIMINADO");
			if(eliminado){				
				setImporteCancelado(getImporteCancelado()+numero);
				setRegistrosCancelados(getRegistrosCancelados()+1);
			}else{
				setImporte(getImporte()+numero);
				setRegistros(getRegistros()+1);
			}
			
		}
		
		/*
		 * (non-Javadoc)
		 * @see com.luxsoft.siipap.em.replica.importadores.dbf.DBFRowFilter#incluir(java.util.Map)
		 */
		public boolean incluir(Map<String, Object> row) {
			
			double res=getSafaDouble(row, getPrefix()+"IDENOPE");
			boolean ok=(res==1.0);
			if(ok){
				Date fo=(Date)row.get(getPrefix()+"FECHA");
				return DateUtils.isSameDay(getDia(), fo); 
			}
			return false;
		}
		
		

		public double getImporte() {
			return importe;
		}

		public void setImporte(double importe) {
			this.importe = importe;
		}

		public int getRegistros() {
			return registros;
		}

		public void setRegistros(int registros) {
			this.registros = registros;
		}

		public String getPrefix() {
			return prefix;
		}

		public void setPrefix(String prefix) {
			this.prefix = prefix;
		}

		public Date getDia() {
			return dia;
		}
		
		
		
		public double getImporteCancelado() {
			return importeCancelado;
		}

		public void setImporteCancelado(double importeCancelado) {
			this.importeCancelado = importeCancelado;
		}

		public int getRegistrosCancelados() {
			return registrosCancelados;
		}

		public void setRegistrosCancelados(int registrosCancelados) {
			this.registrosCancelados = registrosCancelados;
		}

		public double getSafaDouble(Map<String, Object> row,String key){
			Number res=(Number)row.get(key);
			return res!=null?res.doubleValue():0;
		}
		
		public long getSafaLong(Map<String, Object> row,String key){
			Number res=(Number)row.get(key);
			return res!=null?res.longValue():0;
		}
		
		public int getSafaInt(Map<String, Object> row,String key){
			Number res=(Number)row.get(key);
			return res!=null?res.intValue():0;
		}
		
	}
	
	
	
	
	public static void main(String[] args) throws IOException {
		ValidadorDeImportacionVentasDBF val=new ValidadorDeImportacionVentasDBF();
		List<SimpleValidator> res=val.validar(DateUtil.toDate("02/03/2009"));
		for(SimpleValidator r:res){
			System.out.println(r);
		}
	}

}
